package tui

import (
	"clean/infra/config"
	"clean/infra/io/driver"
	"clean/usecase"
	"fmt"
	"github.com/jroimartin/gocui"
	"log"
)

type ServerGocui struct {
	g   *gocui.Gui
	app usecase.Input
}

func NewServerGocui(cfg config.Config, app usecase.Input) io_driver.Server {
	s := &ServerGocui{
		app: app,
	}

	g, err := gocui.NewGui(gocui.OutputNormal)
	if err != nil {
		log.Panicln(err)
	}
	defer g.Close()

	s.g = g

	g.SetManagerFunc(layout)

	if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
		log.Panicln(err)
	}

	if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
		log.Panicln(err)
	}
	return s
}

func (s *ServerGocui) Start() error {
	return s.g.MainLoop()
}

var DefaultEditor gocui.Editor = gocui.EditorFunc(simpleEditor)

func simpleEditor(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) {
	switch {
	case ch != 0 && mod == 0:
		v.EditWrite(ch)
	case key == gocui.KeySpace:
		v.EditWrite(' ')
	case key == gocui.KeyBackspace || key == gocui.KeyBackspace2:
		v.EditDelete(true)
	case key == gocui.KeyEnter:
		fmt.Fprintln(v)
	}

}

func layout(g *gocui.Gui) error {
	maxX, maxY := g.Size()
	if v, err := g.SetView("side", -1, -1, int(0.2*float32(maxX)), maxY-5); err != nil &&
		err != gocui.ErrUnknownView {
		fmt.Fprintln(v, "side")
		return err
	}
	if v, err := g.SetView("main", int(0.2*float32(maxX)), -1, maxX, maxY-5); err != nil &&
		err != gocui.ErrUnknownView {
		fmt.Fprintln(v, "main")
		return err
	}
	if _, err := g.SetView("cmdline", -1, maxY-5, maxX, maxY); err != nil &&
		err != gocui.ErrUnknownView {
		return err
	}
	return nil
}

func quit(g *gocui.Gui, v *gocui.View) error {
	return gocui.ErrQuit
}
